package com.wsoft.system.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wsoft.constant.redis.RedisKeyConstant;
import com.wsoft.core.annotation.GetRedisCache;
import com.wsoft.core.annotation.InitRedisCache;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.service.RedisService;
import com.wsoft.enums.ConfigInitEnum;
import com.wsoft.system.dto.TsConfigDto;
import com.wsoft.system.entity.TsConfigEntity;
import com.wsoft.system.entity.TsConfigInfoEntity;
import com.wsoft.system.mapper.TsConfigMapper;
import com.wsoft.system.query.config.ConfigListQuery;
import com.wsoft.system.service.ITsConfigInfoService;
import com.wsoft.system.service.ITsConfigService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统配置表 服务实现类
 * </p>
 *
 * @author kyle
 * @since 2024年09月01日 08:51:54
 */
@Service
public class TsConfigServiceImpl extends ServiceImpl<TsConfigMapper, TsConfigEntity> implements ITsConfigService {

    @Resource
    private RedisService redisService;
    @Resource
    private ITsConfigInfoService tsConfigInfoService;

    private final String MEMBER = "member";

    private final String ORG = "org";

    @Override
    @InitRedisCache(type = RedisKeyConstant.CONFIG_CACHE_ALL,
            value = RedisKeyConstant.REDIS_NULL)
    public boolean insert(TsConfigDto dto) {
        TsConfigEntity entity = Convert.convert(TsConfigEntity.class, dto);
        QueryWrapper<TsConfigEntity> query = new QueryWrapper<>();
        query.lambda().eq(TsConfigEntity::getCode, entity.getCode());
        if (count(query)>0){
            Asserts.fail("[ts.code.exist]");
        }
        return save(entity);
    }

    @Override
    @InitRedisCache(types = {RedisKeyConstant.CONFIG_CACHE_ALL,RedisKeyConstant.CONFIG_CACHE_CODE,RedisKeyConstant.CONFIG_CACHE},
                    values = {RedisKeyConstant.REDIS_NULL,"code","id"})
    public boolean update(TsConfigDto dto) {
        TsConfigEntity entity = Convert.convert(TsConfigEntity.class, dto);
        QueryWrapper<TsConfigEntity> query = new QueryWrapper<>();
        query.lambda().eq(TsConfigEntity::getCode, entity.getCode())
                .ne(TsConfigEntity::getId,entity.getId());
        if (count(query)>0){
            Asserts.fail("[ts.code.exist]");
        }
        return updateById(entity);
    }

    @Override
    @InitRedisCache(types = {RedisKeyConstant.CONFIG_CACHE_ALL,RedisKeyConstant.CONFIG_CACHE},
            values = {RedisKeyConstant.REDIS_NULL,RedisKeyConstant.REDIS_SELF})
    public boolean delete(Long id) {
        TsConfigEntity config = getConfig(id);
        boolean b = removeById(id);
        if (b){
            List<TsConfigInfoEntity> info = tsConfigInfoService.getConfigInfoByCode(config.getCode());
            for (TsConfigInfoEntity tsConfigInfoEntity : info) {
                tsConfigInfoService.delete(tsConfigInfoEntity.getId());
            }
            redisService.del(RedisKeyConstant.CONFIG_CACHE_CODE+config.getCode());
        }
        return b;
    }

    @Override
    @GetRedisCache(type = RedisKeyConstant.CONFIG_CACHE,
    value = RedisKeyConstant.REDIS_SELF)
    public TsConfigEntity getConfig(Long id) {
        return getById(id);
    }

    @Override
    @GetRedisCache(type = RedisKeyConstant.CONFIG_CACHE_CODE,
                    value =RedisKeyConstant.REDIS_SELF)
    public TsConfigEntity getConfigByCode(String code) {
        QueryWrapper<TsConfigEntity> query = new QueryWrapper<>();
        query.lambda().eq(TsConfigEntity::getCode,code);
        return getOne(query);
    }

    @Override
    public List<TsConfigEntity> listConfig(ConfigListQuery query) {
        QueryWrapper<TsConfigEntity> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(query.getCode())) {
            queryWrapper.lambda().eq(TsConfigEntity::getCode, query.getCode());
        }
        if (StrUtil.isNotBlank(query.getName())) {
            queryWrapper.lambda().like(TsConfigEntity::getName, query.getName());
        }
        if (query.getIsMemberInit() != null) {
            queryWrapper.lambda().eq(TsConfigEntity::getIsMemberInit, query.getIsMemberInit());
        }
        return list(queryWrapper);
    }
    @Override
    public List<TsConfigEntity> getConfigurableCode(String type) {
        List<TsConfigEntity> entities = listConfigCache();
        if (ORG.equals(type)){
            return entities.stream().filter(item -> item.getIsOrgInit().equals(ConfigInitEnum.ENABLE.getValue())).collect(Collectors.toList());
        }
        if (MEMBER.equals(type)){
            return entities.stream().filter(item -> item.getIsMemberInit().equals(ConfigInitEnum.ENABLE.getValue())).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    @Override
    @GetRedisCache(type = RedisKeyConstant.CONFIG_CACHE_ALL,
                   value = RedisKeyConstant.REDIS_NULL)
    public List<TsConfigEntity> listConfigCache() {
        return list();
    }
}
